package com.sky.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.sky.constant.MessageConstant;
import com.sky.context.BaseContext;
import com.sky.dto.OrdersPageQueryDTO;
import com.sky.dto.OrdersSubmitDTO;
import com.sky.entity.AddressBook;
import com.sky.entity.OrderDetail;
import com.sky.entity.Orders;
import com.sky.entity.ShoppingCart;
import com.sky.exception.OrderBusinessException;
import com.sky.mapper.AddressBookMapper;
import com.sky.mapper.CartMapper;
import com.sky.mapper.OrderDetailMapper;
import com.sky.mapper.OrderMapper;
import com.sky.result.PageResult;
import com.sky.service.OrderService;
import com.sky.vo.OrderSubmitVO;
import com.sky.vo.OrderVO;
import com.sky.vo.TurnoverReportVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @Description:
 * @author: nianqiang
 * @Version: V1.0
 */
@Service
public class OrderServiceImpl implements OrderService {


		@Autowired
		private AddressBookMapper addressBookMapper;
		@Autowired
		private CartMapper cartMapper;

		@Autowired
		private OrderMapper orderMapper;

		@Autowired
		private OrderDetailMapper orderDetailMapper;

		/**
		 * 订单搜索
		 *
		 * @param ordersPageQueryDTO
		 * @return
		 */
		public PageResult conditionSearch(OrdersPageQueryDTO ordersPageQueryDTO) {
				PageHelper.startPage(ordersPageQueryDTO.getPage(), ordersPageQueryDTO.getPageSize());

				Page<Orders> page = orderMapper.pageQuery(ordersPageQueryDTO);

				// 部分订单状态，需要额外返回订单菜品信息，将Orders转化为OrderVO
				List<OrderVO> orderVOList = getOrderVOList(page);

				return new PageResult(page.getTotal(), orderVOList);
		}


		private List<OrderVO> getOrderVOList(Page<Orders> page) {
				// 需要返回订单菜品信息，自定义OrderVO响应结果
				List<OrderVO> orderVOList = new ArrayList<>();

				List<Orders> ordersList = page.getResult();
				if (!CollectionUtils.isEmpty(ordersList)) {
						for (Orders orders : ordersList) {
								// 将共同字段复制到OrderVO
								OrderVO orderVO = new OrderVO();
								BeanUtils.copyProperties(orders, orderVO);
								String orderDishes = getOrderDishesStr(orders);

								// 将订单菜品信息封装到orderVO中，并添加到orderVOList
								orderVO.setOrderDishes(orderDishes);
								orderVOList.add(orderVO);
						}
				}
				return orderVOList;
		}


		/**
		 * 根据订单id获取菜品信息字符串
		 *
		 * @param orders
		 * @return
		 */
		private String getOrderDishesStr(Orders orders) {
				// 查询订单菜品详情信息（订单中的菜品和数量）
				List<OrderDetail> orderDetailList = orderDetailMapper.getByOrderId(orders.getId());

				// 将每一条订单菜品信息拼接为字符串（格式：宫保鸡丁*3；）
				List<String> orderDishList = orderDetailList.stream().map(x -> {
						String orderDish = x.getName() + "*" + x.getNumber() + ";";
						return orderDish;
				}).collect(Collectors.toList());

				// 将该订单对应的所有菜品信息拼接在一起
				return String.join("", orderDishList);
		}


		/**
		 * 下单: 从购物车中将数据取出来,分别保存到订单表和订单明细表,保存成功后需要将购物车数据删了
		 * @param ordersSubmitDTO
		 * @return
		 */
		@Override
		@Transactional(rollbackFor = Exception.class)  // 解决事务问题:执行结果前后一致
		public OrderSubmitVO submitOrder(OrdersSubmitDTO ordersSubmitDTO) {
				//1 参数校验
				//地址是否存在校验
				AddressBook addressBook = addressBookMapper.getById(ordersSubmitDTO.getAddressBookId());
				if (addressBook == null) {
						throw new OrderBusinessException("配送地址不能为空");
				}
				//当前用户是否登录
				Long userId = BaseContext.getCurrentId();
				if (userId == null) {
						throw new OrderBusinessException("下单必须要求登录");
				}

				//2 查询我的购物车
				List<ShoppingCart> cartList = cartMapper.findByQuery(ShoppingCart.builder().userId(userId).build());
				//3 如果购物车数据为空则抛异常
				if (cartList == null || cartList.size() == 0) {
						throw new OrderBusinessException("购物车为空,不能下单");
				}
				//4 保存订单数据到订单表 1条
				Orders orders = new Orders();
				BeanUtils.copyProperties(ordersSubmitDTO, orders);
				//** 订单编号 支付使用
				orders.setNumber(String.valueOf(System.currentTimeMillis()));
				//待付款
				orders.setStatus(1);
				orders.setUserId(userId);
				orders.setOrderTime(LocalDateTime.now());
				//微信支付
				orders.setPayMethod(1);
				//未支付
				orders.setPayStatus(1);
				orders.setPhone(addressBook.getPhone());
				orders.setAddress(addressBook.getDetail());
				orders.setUserName(addressBook.getConsignee());
				orders.setConsignee(addressBook.getConsignee());
				//预计送达时间
				orders.setEstimatedDeliveryTime(LocalDateTime.now().minusHours(1));
				orders.setPackAmount(3);
				orders.setTablewareNumber(1);
				orders.setTablewareStatus(1);
				orderMapper.insert(orders);


				//5 保存订单明细数据到订单明细中 n条
				List<OrderDetail> orderDetails = new ArrayList<>();
				for (ShoppingCart cart : cartList) {
						OrderDetail orderDetail = new OrderDetail();
						BeanUtils.copyProperties(cart, orderDetail);
						//*** 订单id: 标识订单和订单明细之间 1对多关系
						orderDetail.setOrderId(orders.getId());
						orderDetails.add(orderDetail);
				}
				//执行批量保存订单明细
				orderDetailMapper.insertBatch(orderDetails);

				//6 清理购物车
				cartMapper.deleteByUserId(userId);

				//7 封装结果并返回
				OrderSubmitVO orderSubmitVO =	OrderSubmitVO.builder()
																.orderAmount(orders.getAmount())
																.orderNumber(orders.getNumber())
																.orderTime(orders.getOrderTime())
																.id(orders.getId())
																.build();
				return orderSubmitVO;
		}


		/**
		 * 用户端订单分页查询
		 *
		 * @param pageNum
		 * @param pageSize
		 * @param status
		 * @return
		 */
		public PageResult pageQuery4User(int pageNum, int pageSize, Integer status) {
				// 设置分页
				PageHelper.startPage(pageNum, pageSize);

				OrdersPageQueryDTO ordersPageQueryDTO = new OrdersPageQueryDTO();
				ordersPageQueryDTO.setUserId(BaseContext.getCurrentId());
				ordersPageQueryDTO.setStatus(status);

				// 分页条件查询
				Page<Orders> page = orderMapper.pageQuery(ordersPageQueryDTO);

				List<OrderVO> list = new ArrayList();

				// 查询出订单明细，并封装入OrderVO进行响应
				if (page != null && page.getTotal() > 0) {
						for (Orders orders : page) {
								Long orderId = orders.getId();// 订单id

								// 查询订单明细
								List<OrderDetail> orderDetails = orderDetailMapper.getByOrderId(orderId);

								OrderVO orderVO = new OrderVO();
								BeanUtils.copyProperties(orders, orderVO);
								orderVO.setOrderDetailList(orderDetails);

								list.add(orderVO);
						}
				}
				return new PageResult(page.getTotal(), list);
		}

		/**
		 * 营业额统计
		 * @param begin
		 * @param end
		 * @return
		 */
		@Override
		public TurnoverReportVO turnoverStatistics(LocalDate begin, LocalDate end) {

				// 构建X轴(横坐标 日期范围)
				//2024-06-21,2024-06-22,2024-06-23,.....
				List<LocalDate> xDateList = new ArrayList<>();
				xDateList.add(begin);
				while (!begin.equals(end)) {
						begin = begin.plusDays(1);
						xDateList.add(begin);
				}

				// 构建 Y轴(纵坐标 对应的日期的营业总额)
				List<Double> yDataAmounts = new ArrayList<>();
				for (LocalDate date : xDateList) {
						Map map = new HashMap();
						map.put("status", Orders.COMPLETED);
						// 查某一天营业额 获取到当天 0:0:0 -- 当天 23:59:59
						LocalDateTime beginTime = LocalDateTime.of(date, LocalTime.MIN);
						LocalDateTime endTime = LocalDateTime.of(date, LocalTime.MAX);
						map.put("begin", beginTime);
						map.put("end", endTime);
						Double sumMoney = orderMapper.sumByMap(map);
						if (sumMoney == null) {
								sumMoney = 0D;
						}
						yDataAmounts.add(sumMoney);
				}

				// 封装结果并返回
				TurnoverReportVO reportVO =
								TurnoverReportVO.builder()
												.dateList(StringUtils.join(xDateList, ","))
												.turnoverList(StringUtils.join(yDataAmounts, ","))
												.build();
				return reportVO;
		}
}
